﻿using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Runtime.Serialization.Formatters.Binary;
using System.Threading;

namespace Fadd.Net
{
	/// <summary>
	/// Send or receive file(s).
	/// </summary>
	/// <remarks>
	/// Binary format: [headersize][BinaryFormatted header class][data]
	/// </remarks>
	internal class FileSender
	{
		private readonly byte[] _inbuffer = new byte[65535];
		private readonly Socket _socket;

		public FileSender(Socket socket)
		{
			_socket = socket;
		}

		public FileSender()
		{
		}



		public static void Send(IPEndPoint endPoint, string fileName)
		{
			var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
			socket.Connect(endPoint);
			var transfer = new FileTransfer(socket);
			transfer.Send(fileName);
		}

		public void Send(string fileName)
		{
			var fi = new FileInfo(fileName);
			var formatter = new BinaryFormatter();
			var headerStream = new MemoryStream();
			var header = new FileHeader { FileName = fi.Name + "." + fi.Extension, Size = (int)fi.Length, ModifiedAt = fi.LastWriteTimeUtc };
			formatter.Serialize(headerStream, header);
			headerStream.Flush();
			headerStream.Position = 0;

			_socket.Send(BitConverter.GetBytes((Int32)headerStream.Length));
			_socket.Send(headerStream.GetBuffer(), 0, (int)headerStream.Length, SocketFlags.None);

			var buffer = new byte[65535];
			using (var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
			{
				int bytesRead = fs.Read(buffer, 0, buffer.Length);
				while (bytesRead > 0)
				{
					_socket.Send(buffer, 0, bytesRead, SocketFlags.None);
					bytesRead = fs.Read(buffer, 0, buffer.Length);
				}
			}
		}

	}
}